/************************************************************************/
/* Name : Kiwon Yun
/* Partner's name : Eric Rooney
/* File Name : Dealer.h
/* The name of assignment : Iteration 2
/************************************************************************/

#ifndef DEALER_H
#define DEALER_H

#include "Common.h"
#include "Deck.h"
#include "Card.h"
#include "Player.h"
#include "GameInfo.h"
#include "Betting.h"
#include "RuleManager.h"
#include "RoundInfo.h"

/************************************************************************/
/* Dealer class manages players, hands, deck.
/* Players can join a game, but they should not always join a game.
/* Therefore, dealer have not only hands' list, but also players' list.
/************************************************************************/

class Dealer
{
public:

	Dealer(void);
	virtual ~Dealer(void);

	/***********************************************************************
	* Create a deck, and create cards. 
	* After that, deal five cards for each player.
	*
	* Parameter
	*	a_mode : 'standard mode' or 'test mode'
	*	a_strTestFileName : a test file name for test mode
	*
	* Remark : basic mode is standard mode.
	************************************************************************/
	void CreateGame( E_MODE a_mode = STANDARD_MODE, char* a_strTestFileName = NULL );

	/***********************************************************************
	* Clear hands, create deck, and deal
	************************************************************************/
	void CreateDeckAndDeal();

	/***********************************************************************
	* Clear a game. Delete a deck, and clear vectors that dealer have.
	************************************************************************/
	void ClearGame();

	/***********************************************************************
	* A player and its hand add to a game.
	*
	* Remark : All players always join a game in this version.
	*		   However, it can be different in next version.
	************************************************************************/
	void AddPlayer( const char* a_strPlayerName );

	/***********************************************************************
	* Return the number of cards remaining in the deck.
	************************************************************************/
	int GetRemaingCardNum();

	/***********************************************************************
	* show hands of all player in the game.
	************************************************************************/
	void ShowHands();


	/***********************************************************************
	* Send message to player to discard
	************************************************************************/
	void Discard(int m_nCard1,int m_nCard2,int m_nCard3);

	/***********************************************************************
	* show hands of the current player.
	************************************************************************/
	void ShowCurHand();

	/***********************************************************************
	* Return the number of players in this game.
	* It doesn't matter whether he actually join this game or not.
	* The player just viewing in this game is counted.
	************************************************************************/
	int GetPlayersNum();
	
	/***********************************************************************
	* Return the number of hands in this game.
	* The only hand actually joined this game is counted.
	* A folding player can't have hand.
	************************************************************************/
	int GetHandsNum();

	/***********************************************************************
	* Return the name of the current player.
	************************************************************************/
	char* GetCurPlayerName();
	
	/***********************************************************************
	* Go on to the next player
	*
	* Return
	*		if the next player exists, return true.
	*		if the next player doesn't exist, return false
	************************************************************************/
	bool GotoNextPlayer();

	/***********************************************************************
	* Draws a card from the deck, and the card gives the player
	* 
	* Parameter
	*	a_pPlayer : the player who requests a card
	************************************************************************/
	void RequestCard( Player* a_pPlayer );

	/***********************************************************************
	* Process about the next turn
	************************************************************************/
	void ProcessNextTurn();

	/***********************************************************************
	* Check the information of money of all players.
	* If the number of players that have some money is less than 1, the game is ended.
	************************************************************************/
	void CheckMoneyOfPlayers();
	
	/***********************************************************************
	* Decide winning player about this round.
	************************************************************************/
	void CalcRankScore();

	/***********************************************************************
	* Ante
	************************************************************************/
	void Ante();

	/***********************************************************************
	* for showing some log
	************************************************************************/
	void ShowTestLog();

	/***********************************************************************
	* Raise
	************************************************************************/
	void Raise(int * m_nAmount);
	
	/***********************************************************************
	* Call
	************************************************************************/
	void Call();
	
	/***********************************************************************
	* Show money
	************************************************************************/
	void ShowMoney();

	/***********************************************************************
	* Fold
	************************************************************************/
	void Fold();
	
	/***********************************************************************
	* Return number of rounds
	************************************************************************/
	int GetSubRoundNum();

	/***********************************************************************
	* Return number of raises
	************************************************************************/
	int GetRaises();

	/***********************************************************************
	*Distribute the winnings
	************************************************************************/
	void DistributeMoney();

	/***********************************************************************
	* whether player can bet in this round or not
	************************************************************************/
	bool IsCanBet();

	/***********************************************************************
	*Set the amount of money each player starts with
	************************************************************************/
	void SetBetMoney(int a_nBetMoney);

private:

	/* A pointer of the deck */
	Deck* m_pDeck;

	/* A vector containing the hands in the game. */
	vector <Hand*> m_vecHand;

	/* A vector containing the players in the game. */
	vector <Player*> m_vecPlayer;

	/* An index of the current player */
	vector<Player*>::iterator itCurPlayer;

	/* Pointer to Game info object*/
	GameInfo* m_pGameInfo;
	/* Pointer to round info object*/
	RoundInfo* m_pCurRoundInfo;

	/* pointer to rule manager object*/
	RuleManager* m_pRuleManager;

	/* pointer to betting object*/
	Betting* m_pBetting;

	E_MODE m_exeMode;
	/* store name of test file*/
	char* m_strTestFileName;

	/* store amount bet*/
	int m_nBetMoney;
};

#endif
